import axios, { AxiosError, AxiosResponse } from "axios";
import { BaseResponse } from "./types";
import { requestInterceptor, requestInterceptorError, responseInterceptor, responseInterceptorError } from "./interceptors";

/**
 * 基础配置
 */
axios.create({
  timeout: 5 * 1000, //60s的超时时间
  headers: {},
});

/**
 * 添加请求拦截器
 */
axios.interceptors.request.use(requestInterceptor, requestInterceptorError);

/**
 * 添加响应拦截器
 */
axios.interceptors.response.use(responseInterceptor, responseInterceptorError);


/** 封装http请求 */
const request = {
  get: <T>(url: string, options?: OptionTypes): Promise<BaseResponse<T>> => {
    return new Promise((resolve, reject) => {
      axios({
        isErrorToast: true,
        ...options,
        url: url,
        method: "get",
      })
        .then((res: AxiosResponse<BaseResponse<T>>) => {
          resolve(res.data);
        })
        .catch((err: AxiosError<BaseResponse<T>>) => {
          reject(err.response.data);
        });
    });
  },
  post: <T>(url: string, options?: OptionTypes): Promise<BaseResponse<T>> => {
    const { data = {}, requestType } = options || {};
    if (requestType == "form") {
      const formData = new FormData();
      Object.keys(data).forEach((key) => {
        if (data[key]) {
          formData.append(key, data[key]);
        }
      });
      if (options) {
        options.data = formData;
      }
    }

    return new Promise((resolve, reject) => {
      axios({
        isErrorToast: true,
        ...options,
        url: url,
        method: "post",
      })
        .then((res: AxiosResponse<BaseResponse<T>>) => {
          resolve(res.data);
        })
        .catch((err: AxiosError<BaseResponse<T>>) => {
          reject(err.response.data);
        });
    });
  },
  put: <T>(url: string, options?: OptionTypes): Promise<BaseResponse<T>> => {
    return new Promise((resolve, reject) => {
      axios({
        isErrorToast: true,
        ...options,
        url: url,
        method: "put",
      })
        .then((res: AxiosResponse<BaseResponse<T>>) => {
          resolve(res.data);
        })
        .catch((err: AxiosError<BaseResponse<T>>) => {
          reject(err.response.data);
        });
    });
  },
  delete: <T>(url: string, options?: OptionTypes): Promise<BaseResponse<T>> => {
    return new Promise((resolve, reject) => {
      axios({
        isErrorToast: true,
        ...options,
        url: url,
        method: "delete",
      })
        .then((res: AxiosResponse<BaseResponse<T>>) => {
          resolve(res.data);
        })
        .catch((err: AxiosError<BaseResponse<T>>) => {
          reject(err.response.data);
        });
    });
  },
};

export default request;
